module.exports = function (httpServer) {
    const log4js = require('log4js');


    const logger = log4js.getLogger('websocket');
    log4js.getLogger().debug('Startup websocket');

    var WebSocketServer = require('websocket').server;

    var ws_server = new WebSocketServer({
        httpServer: httpServer,
        autoAcceptConnections: false,
    });

    const resolveCode = function (doc, node) {
        return eval(`(${node.strValue})`);
    };
    const yamlOptions = {
        customTags: [{
                tag: "!fn",
                class: Function,
                resolve: resolveCode
            },
            {
                tag: "!re",
                class: RegExp,
                resolve: resolveCode
            },
        ]
    };
    let mockRawTemplates = require("fs").readFileSync("cfg/mock/mock_ws.yml", {
        encoding: "utf-8"
    });
    let mockTemplates = require("yaml").parse(mockRawTemplates, yamlOptions);

    function originIsAllowed(origin) {
        logger.debug(`Connection from origin ${origin}`);
        // put logic here to detect whether the specified origin is allowed.
        return true;
    }
    ws_server.on('request', (request) => {
        if (!originIsAllowed(request.origin)) {
            // Make sure we only accept requests from an allowed origin
            request.reject();
            logger.debug(' Connection from origin ' + request.origin + ' rejected.');
            return;
        }
        // var connection = request.accept('echo-protocol', request.origin);
        var connection = request.accept(null, request.origin);
        logger.info(' Connection accepted.');
        connection.on('message', function (message) {
            if (message.type === 'utf8') {
                logger.debug(`[RECV ${message.utf8Data.length} UTF-8] ${message.utf8Data}`);
                let template = mockTemplates[utf8Data];
                if (!template) {
                    // connection.sendUTF(message.utf8Data);
                    logger.warn(`Template not found`);
                } else {
                    template.forEach(v => {
                        connection.sendUTF(v);
                    });
                }
            } else if (message.type === 'binary') {
                let base64Raw = message.binaryData.toString("base64");
                logger.debug(`[RECV ${message.binaryData.length} Bytes] ${base64Raw}`);
                let template = mockTemplates[base64Raw];
                if (!template) {
                    // connection.sendBytes(message.binaryData);
                    logger.warn(`Template not found`);
                } else {
                    template.forEach(v => {
                        connection.sendBytes(Buffer.from(v, "base64"));
                    });
                }
            }
        });
        connection.on('close', function (reasonCode, description) {
            logger.info(' Peer ' + connection.remoteAddress + ' disconnected.');
        });
    })

}